#include "cmsis_os.h"
#include "main.h"
#include "task_comm.h"
#include <string.h>
#include <stdio.h>
#include "4G_mqtt.h"
#include "oled.h"
#include "usart.h"


volatile uint8_t ml307_rx_byte;
ml307g_t g_ml307g;

extern u8g2_t u8g2;


// 状态机枚举
typedef enum {
    ML307G_STATE_INIT = 0,
    ML307G_STATE_PDP,
    ML307G_STATE_MQTT,
    ML307G_STATE_READY,
    ML307G_STATE_ERROR
} ml307g_state_t;

static ml307g_state_t g_state = ML307G_STATE_INIT;


//=========== 平台钩子 4G_mqtt.h中有指针函数 ============
int ml307g_uart_write(const uint8_t *buf, size_t len) {
    return (HAL_UART_Transmit(&hlpuart1, (uint8_t*)buf, len, 1000) == HAL_OK) ? (int)len : -1;
}

uint32_t ml307g_millis(void) {
    return HAL_GetTick();
}

void ml307g_delay_ms(uint32_t ms) {
    HAL_Delay(ms);
}
// ===================== 回调函数 =====================

// MQTT 连接状态回调
void ml307g_on_connected_cb(int st) {
    if (st) {
        // printf("[4G] MQTT 已连接\r\n");
        g_state = ML307G_STATE_READY;
    } else {
        // printf("[4G] MQTT 断开\r\n");
        g_state = ML307G_STATE_ERROR;  // 断开回退
    }
}

// MQTT 收消息回调
void ml307g_on_msg_cb(const char *topic, const uint8_t *p, size_t n, int qos) {
    (void)qos; // 防止未使用警告

    // printf("[4G] 收到消息 %s: %.*s\r\n", topic, (int)n, p);

    if (strstr((const char*)p, "pump_on")) {
        // TODO: 通知水泵任务执行
        // osMessageQueuePut(pumpQueue, ...);
        // printf("执行泵开命令\r\n");
    }
}


void Comm_Task(void *argument) {
    (void)argument;  // 防止未使用的参数警告

    // 平台钩子初始化
    ml307g_init(&g_ml307g, ml307g_uart_write, ml307g_millis, ml307g_delay_ms);

    g_ml307g.on_connected = ml307g_on_connected_cb;
    g_ml307g.on_msg       = ml307g_on_msg_cb;

    HAL_UART_Receive_IT(&hlpuart1, (uint8_t *)&ml307_rx_byte, 1);

    for (;;) {

        osThreadFlagsWait(0x01, osFlagsWaitAny, osWaitForever);

        switch (g_state) {
        case ML307G_STATE_INIT:
            if (ml307g_modem_basic(&g_ml307g) == 0) {
                g_state = ML307G_STATE_PDP;
            } else {
                // printf("[4G] 初始化失败，重试中...\r\n");
                osDelay(2000);
            }
            break;

        case ML307G_STATE_PDP:
            ml307g_set_apn(&g_ml307g, &(ml307g_pdp_cfg_t){ .apn="cmnet" });
            if (ml307g_pdp_activate(&g_ml307g, 1) == 0) {
                g_state = ML307G_STATE_MQTT;
            } else {
                // printf("[4G] PDP 激活失败，重试中...\r\n");
                osDelay(2000);
            }
            break;

        case ML307G_STATE_MQTT:
            ml307g_mqtt_cfg(&g_ml307g, &(ml307g_mqtt_cfg_t){
                .connect_id=0, .version=3, .keepalive_s=60, .clean_session=1,
                .client_id="IMEI",
                .username="doiot",
                .password="mqtt",
                .reconn_times=-1,
                .reconn_interval_s=5,
            });
                if (ml307g_mqtt_connect(&g_ml307g, "mqtt.doiot.cn", 1883) == 0) {
                ml307g_mqtt_sub(&g_ml307g, "node/soil/cmd", 0);
                // 等 on_connected 回调把状态切到 READY
            } else {
                // printf("[4G] MQTT 连接失败，重试中...\r\n");
                osDelay(2000);
            }
            break;

        case ML307G_STATE_READY:
            // 发布传感器数据
            {
                char msg[64];
                snprintf(msg, sizeof(msg), "temp=25,hum=60");
                ml307g_mqtt_pub(&g_ml307g, "node/soil/data",
                                (const uint8_t*)msg, strlen(msg), 0, 0);
                // printf("[4G] 上传数据: %s\r\n", msg);
            }
            osDelay(10000);
            break;

        case ML307G_STATE_ERROR:
            // 出错 → 回到初始化，重新走流程
            osDelay(2000);
            g_state = ML307G_STATE_INIT;
            break;
        }
    }
}


void ML307_RxHandler(void) {
    ml307g_feed_byte(&g_ml307g, ml307_rx_byte);
    HAL_UART_Receive_IT(&hlpuart1, (uint8_t *)&ml307_rx_byte, 1);
}


void stop2_init_task_comm(void) {

    // 4G模块
    ml307g_init(&g_ml307g, ml307g_uart_write, ml307g_millis, ml307g_delay_ms);

    g_ml307g.on_connected = ml307g_on_connected_cb;
    g_ml307g.on_msg       = ml307g_on_msg_cb;

}



// ------------------------------后期修改，加入imei-----------------------------
// // 全局保存 IMEI
// static char g_imei[32] = {0};
//
// // 例子：获取 IMEI 的函数（你可以在 ml307g.c 里实现）
// int ml307g_get_imei(ml307g_t *h, char *buf, size_t len) {
//     sendf(h, "AT+CGSN\r");
//     if (wait_for(h, 2000, "OK", NULL) == 0) {
//         // 假设 h->line 里有 IMEI
//         strncpy(buf, h->line, len - 1);
//         buf[len - 1] = '\0';
//         return 0;
//     }
//     return -1;
// }
// case ML307G_STATE_INIT:
// if (ml307g_modem_basic(&g_ml307g) == 0) {
//     // 获取 IMEI
//     if (ml307g_get_imei(&g_ml307g, g_imei, sizeof(g_imei)) == 0) {
//         g_state = ML307G_STATE_PDP;
//     } else {
//         osDelay(2000);
//     }
// } else {
//     osDelay(2000);
// }
// break;
// case ML307G_STATE_MQTT:
// ml307g_mqtt_cfg(&g_ml307g, &(ml307g_mqtt_cfg_t){
//     .connect_id=0, .version=3, .keepalive_s=60, .clean_session=1,
//     .client_id=g_imei,   // 用 IMEI 作为唯一 client_id
//     .username="doiot",
//     .password="mqtt",
//     .reconn_times=-1,
//     .reconn_interval_s=5,
// });
// if (ml307g_mqtt_connect(&g_ml307g, "mqtt.doiot.cn", 1883) == 0) {
//     // 每个设备只订阅自己的命令主题
//     char topic_cmd[64];
//     snprintf(topic_cmd, sizeof(topic_cmd), "device/%s/cmd", g_imei);
//     ml307g_mqtt_sub(&g_ml307g, topic_cmd, 0);
// } else {
//     osDelay(2000);
// }
// break;
//
// case ML307G_STATE_READY: {
//     // 发布传感器数据到自己独立的 topic
//     char topic_data[64];
//     snprintf(topic_data, sizeof(topic_data), "device/%s/data", g_imei);
//
//     char msg[64];
//     snprintf(msg, sizeof(msg), "temp=25,hum=60");
//
//     ml307g_mqtt_pub(&g_ml307g, topic_data,
//                     (const uint8_t*)msg, strlen(msg), 0, 0);
//
//     osDelay(10000);
//     break;
// }





// -----------------简洁-----------------
// ml307g_t g_ml307g;
//
// void Task_4G(void *argument)
// {
//     // 初始化 ML307G 驱动
//     ml307g_init(&g_ml307g, ml307g_uart_write, ml307g_millis, ml307g_delay_ms);
//
//     // 设置回调（收到消息时丢进队列/打印）
//     g_ml307g.on_connected = [](int st){
//         if (st) {
//             printf("4G 已连接 MQTT\r\n");
//         } else {
//             printf("4G 已断开 MQTT\r\n");
//         }
//     };
//     g_ml307g.on_msg = [](const char *topic, const uint8_t *p, size_t n, int qos){
//         printf("收到主题 %s: %.*s\r\n", topic, n, p);
//         // TODO: 可投递到显示队列 / 控制任务
//     };
//
//     // 1. 模块基础检测
//     ml307g_modem_basic(&g_ml307g);
//
//     // 2. 配置 APN 并激活
//     ml307g_set_apn(&g_ml307g, &(ml307g_pdp_cfg_t){ .apn="cmnet" });
//     ml307g_pdp_activate(&g_ml307g, 1);
//
//     // 3. 配置 MQTT
//     ml307g_mqtt_cfg(&g_ml307g, &(ml307g_mqtt_cfg_t){
//         .connect_id=0, .version=3, .keepalive_s=60, .clean_session=1,
//         .client_id="soil_node_001",
//         .username="u",
//         .password="p",
//         .reconn_times=-1,
//         .reconn_interval_s=5,
//     });
//
//     // 4. 连接 MQTT
//     ml307g_mqtt_connect(&g_ml307g, "broker.hivemq.com", 1883);
//
//     // 5. 订阅主题
//     ml307g_mqtt_sub(&g_ml307g, "node/soil/cmd", 0);
//
//     // 任务循环：每隔 10 秒发一次数据
//     for (;;) {
//         const char *msg = "temp=25,hum=60";
//         ml307g_mqtt_pub(&g_ml307g, "node/soil/data",
//                         (const uint8_t*)msg, strlen(msg),
//                         0, 0);
//
//         osDelay(10000);
//     }
// }
